package org.embedchat.database.dao;

import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StaleObjectStateException;
import org.hibernate.cfg.AnnotationConfiguration;

import org.embedchat.entity.ChatRoom;
import org.embedchat.entity.User;

public class HibernateUtil {

	private static Log log = LogFactory.getLog(HibernateUtil.class);

	private static final SessionFactory sessionFactory;

	static {
		try {
			sessionFactory = new AnnotationConfiguration()
			.addPackage("org.embedchat.server.entity")
			.addAnnotatedClass(ChatRoom.class)
			.addAnnotatedClass(User.class)
			.setProperties(getProperties())
			.buildSessionFactory();
		} catch (Throwable ex) {
			log.error(ex, ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static Session getSessionAndBeginTransaction() throws HibernateException {
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		return session;
	}

	public static void commitTransaction() {
		try {
			sessionFactory.getCurrentSession().getTransaction().commit();
		} catch (StaleObjectStateException staleEx) {
			log.error("This interceptor does not implement optimistic concurrency control!");
			log.error("Your application will not work until you add compensation actions!");
			throw staleEx;
		} catch (Throwable ex) {
			log.error(ex, ex);
			try {
				if (sessionFactory.getCurrentSession().getTransaction().isActive()) {
					log.debug("Trying to rollback database transaction after exception");
					sessionFactory.getCurrentSession().getTransaction().rollback();
				}
			} catch (Throwable rbEx) {
				log.error("Could not rollback transaction after exception!",
						rbEx);
			}
		}
	}

	public static Properties getProperties() {
		Properties properties = new Properties();
		properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
		properties.put("hibernate.connection.driver_class",	"org.hsqldb.jdbcDriver");
		properties.put("hibernate.connection.url", "jdbc:hsqldb:mem:chat");
		properties.put("hibernate.connection.username", "sa");
		properties.put("hibernate.connection.password", "");
		properties.put("hibernate.connection.pool_size", "1");
		properties.put("hibernate.current_session_context_class", "thread");
		properties.put("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
		properties.put("hibernate.show_sql", "false");
		properties.put("hibernate.hbm2ddl.auto", "update");
		return properties;
	}
}